﻿using Abp.Domain.Repositories;
using Abp.Domain.Services;
using Abp.ObjectMapping;
using Abp.Runtime.Caching;
using AVIS.OutBound.Cities.Cache;
using AVIS.OutBound.Regions;
using AVIS.OutBound.Stores;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AVIS.OutBound.Cities
{
    /// <summary>
    /// 城市的领域服务
    /// </summary>
    public class CityManager : DomainService, ICityManager
    {
        #region 构造函数
        private readonly IRepository<City> _cityRepository;
        private readonly IObjectMapper _objectMapper;
        private readonly ICacheManager _cacheManager;
        private readonly IStoreManager _storeManager;

        public CityManager(IRepository<City> cityRepository,
            IObjectMapper objectMapper,
            ICacheManager cacheManager,
            IStoreManager storeManager)
        {
            _cityRepository = cityRepository;
            _objectMapper = objectMapper;
            _cacheManager = cacheManager;
            _storeManager = storeManager;
        }
        #endregion

        /// <summary>
        /// 获取热门城市
        /// </summary>
        /// <returns></returns>
        public IList<City> GetHotCity()
        {
            var cacheItems = _cacheManager.GetCityCache().Get("HotCity", f =>
            {
                var query = from c in _cityRepository.GetAll()
                            where c.IsHot == true || c.IsTop == true
                            orderby c.CusClick descending, c.CNPY, c.ENName
                            select new CityCacheItem
                            {
                                ENName = c.ENName,
                                CNName = c.CNName,
                                RegionCode = c.RegionCode,
                                CusClick = c.CusClick,
                                IsHot = c.IsHot,
                                IsRed = c.IsRed,
                                IsTop = c.IsTop,
                                CNPY = c.CNPY,
                            };

                return query.ToList();
            });

            return _objectMapper.Map<List<City>>(cacheItems);
        }

        /// <summary>
        /// 获取指定编号的城市信息（ENName）
        /// </summary>
        /// <param name="cityCode">城市英文名</param>
        /// <param name="regionCode">区域编号</param>
        /// <returns></returns>
        public City GetCity(string cityCode, string regionCode)
        {
            var cachekey = cityCode.ToUpper() + "_" + regionCode.ToUpper();
            var cacheItems = _cacheManager.GetCityCache().Get(cachekey,
                k => GetCityCacheItem(cityCode, regionCode));
            return _objectMapper.Map<City>(cacheItems.FirstOrDefault());
        }

        /// <summary>
        /// 获取指定门店编号的城市信息
        /// </summary>
        /// <param name="storeCode">门店编号</param>
        /// <returns></returns>
        public City GetCityByStoreCode(string storeCode)
        {
            var store = _storeManager.GetStoreByCode(storeCode);
            if (store != null && !string.IsNullOrEmpty(store.CityCode) && !string.IsNullOrWhiteSpace(store.RegionCode))
            {
                return GetCity(store.CityCode, store.RegionCode);
            }

            return null;
        }

        #region 私有方法
        /// <summary>
        /// 查询指定门店Code的城市信息
        /// </summary>
        /// <param name="cityCode">城市英文名</param>
        /// <param name="regionCode">区域编号</param>
        /// <returns></returns>
        private List<CityCacheItem> GetCityCacheItem(string cityCode, string regionCode)
        {
            if (string.IsNullOrEmpty(cityCode) || string.IsNullOrEmpty(regionCode))
            {
                Logger.Debug($"获取不到城市信息，因为城市编号（{cityCode}）或区域编号（{regionCode}）为空");
                return null;
            }

            var query = from c in _cityRepository.GetAll()
                        where c.ENName == cityCode && c.RegionCode == regionCode
                        orderby c.IsTop descending, c.IsHot descending
                        select c;
            var city = query.FirstOrDefault();

            // 地区编号（简写，美国只返回 US，加拿大只返回 CA）
            var regionShortCode = new Region { RegionCode = regionCode }.RegionShortCode;
            if (city == null && regionShortCode != regionCode)
            {
                var query1 = from c in _cityRepository.GetAll()
                             where c.ENName == cityCode && c.RegionCode.StartsWith(regionShortCode)
                             orderby c.IsTop descending, c.IsHot descending
                             select c;
                city = query1.FirstOrDefault();
            }

            // 如果获取不到城市，则需要记录日志
            if (city == null)
            {
                Logger.Debug($"获取不到城市信息，城市编号（{cityCode}）或区域编号（{regionCode}）为空");
            }

            var cacheItem = _objectMapper.Map<CityCacheItem>(city);
            return new List<CityCacheItem> { cacheItem };
        }
        #endregion
    }
}
